Skip to content

spec: a figure group's panels nest directly, and the wrapper div goes - #1241

Merged
dereuromark merged 1 commit into
mainfrom
spec/figure-group-flat
Aug 16, 2026
Merged

spec: a figure group's panels nest directly, and the wrapper div goes#1241
dereuromark merged 1 commit into
mainfrom
spec/figure-group-flat

Conversation

@dereuromark

Copy link
Copy Markdown
Contributor

Follow-up to #1122 (and #1215): the <div class="carve-figure-panels"> wrapper is dropped from the composite-figure shape. Panels nest directly in the group figure.

Why

  • HTML content model. A figure holds a figcaption first or last plus arbitrary flow content, and figure is itself flow content - so nested panel figures are exactly what the element admits. The wrapper added no validity and no structure the markup needed (surfaced by the content-model discussion on jgm/djot#31).
  • Pandoc symmetry. The flat form is what Pandoc's writers produce for native subfigures, so the bridge's HTML import and export stay symmetric.
  • Revised before any release. The wrapper was the initial draft shape from the spec PR; no tag has shipped it, so no shipped document changes. §4c records the revision.

What changed

  • PART 9 §4c HTML-shape prose: flat shape, rationale, and the revision note.
  • scripts/spec/html.mjs: the oracle emits the flat shape (panels and preserved stray content sit one level up; zero-panel groups hold their content directly; the group figcaption stays last).
  • Nine corpus cases regenerate: 318-composite-figures, -2, -3, -4, -5, -6, -9, -10, -11. -7 and -8 are untouched (they emit no group).
  • Docs sweep: versioning.md example, graceful-degradation.md and validation.md rows, the examples-section prose, CHANGELOG (still under Unreleased).
  • resources/engine-pin-drift.txt: the pinned carve-js (456ce074) still emits the wrapper, so the nine slugs are declared until the engine updates land and the pin moves. The pin does not move here.

HTML's figure content model is a figcaption first or last plus flow
content, and figure is itself flow content, so the panel figures are
exactly what the group element admits - the intermediate
div.carve-figure-panels added nothing the markup needed and is dropped
from PART 9 section 4c's shape, the oracle, and the nine corpus cases
that emit a group. This is also the shape Pandoc's writers produce for
native subfigures, which keeps HTML import and export symmetric with the
bridge. The wrapper was the initial draft shape and is revised before
any release, so no shipped document ever carried it.

Zero-panel groups hold their preserved content directly; a consumer
selects panels by the carve-figure-panel class, never by position. The
pinned engine still emits the wrapper, so the affected slugs are
declared in the engine-pin-drift file until the engine updates land and
the pin moves.
@dereuromark dereuromark added the enhancement New feature or request label Aug 16, 2026
@dereuromark
dereuromark merged commit 427b125 into main Aug 16, 2026
4 checks passed
@dereuromark
dereuromark deleted the spec/figure-group-flat branch August 16, 2026 10:14
dereuromark added a commit to markup-carve/carve-php that referenced this pull request Aug 16, 2026
PART 9 section 4c revision (markup-carve/carve#1122), ruled before any release
carries the shape. The `<div class="carve-figure-panels">` wrapper is gone:
panels and preserved stray content nest DIRECTLY inside
`<figure class="carve-figure-group">`, one indent level up, with the group's
`<figcaption>` last and `carve-figure-panel` unchanged on each panel.

HTML's content model for `figure` is one `figcaption` first-or-last plus flow
content, and a `figure` is itself flow content - so the wrapper drew a box the
element already provides, and a consumer styling the group can select
`.carve-figure-group > .carve-figure-panel` exactly as it could select the
div. Pandoc's subfigure HTML output has the same flat shape, which the sibling
engines match byte for byte through the shared corpus.

The HTML importer reads the flat shape back: panels are the direct
`figure.carve-figure-panel` children of the group and the group caption is the
direct `figcaption` child - a panel's own caption sits inside the panel
figure, so the direct-child scan never confuses the two. An empty uncaptioned
group keeps the bare-container empty-body form - the PART 10 section 4
exception the bare div takes, and the shape the oracle emits.

The tests/spec submodule pin moves to 427b125 on spec main, the merged
markup-carve/carve#1241, whose corpus pins the flat bytes; all eleven
318-composite-figures documents pass byte for byte.
dereuromark added a commit to markup-carve/carve-php that referenced this pull request Aug 16, 2026
PART 9 section 4c revision (markup-carve/carve#1122), ruled before any release
carries the shape. The `<div class="carve-figure-panels">` wrapper is gone:
panels and preserved stray content nest DIRECTLY inside
`<figure class="carve-figure-group">`, one indent level up, with the group's
`<figcaption>` last and `carve-figure-panel` unchanged on each panel.

HTML's content model for `figure` is one `figcaption` first-or-last plus flow
content, and a `figure` is itself flow content - so the wrapper drew a box the
element already provides, and a consumer styling the group can select
`.carve-figure-group > .carve-figure-panel` exactly as it could select the
div. Pandoc's subfigure HTML output has the same flat shape, which the sibling
engines match byte for byte through the shared corpus.

The HTML importer reads the flat shape back: panels are the direct
`figure.carve-figure-panel` children of the group and the group caption is the
direct `figcaption` child - a panel's own caption sits inside the panel
figure, so the direct-child scan never confuses the two. An empty uncaptioned
group keeps the bare-container empty-body form - the PART 10 section 4
exception the bare div takes, and the shape the oracle emits.

The tests/spec submodule pin moves to 427b125 on spec main, the merged
markup-carve/carve#1241, whose corpus pins the flat bytes; all eleven
318-composite-figures documents pass byte for byte.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant